package com.wefans.wefansapp.activity;

import java.text.DecimalFormat;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.gson.Gson;
import com.wefans.wefansapp.R;
import com.wefans.wefansapp.common.tool.data.MFDataManager;
import com.wefans.wefansapp.common.tool.data.ResGetAppVer;
import com.wefans.wefansapp.common.tool.data.ResGetUser;
import com.wefans.wefansapp.common.tool.data.ResGetVote;
import com.wefans.wefansapp.common.tool.data.ResGetVote.ResGetVoteMainData;
import com.wefans.wefansapp.common.tool.debug.MFDebug;
import com.wefans.wefansapp.common.tool.finals.FEATURES;
import com.wefans.wefansapp.common.tool.network.MFNetworkManager;
import com.wefans.wefansapp.common.tool.network.MFNetworkManager.IOnNetworkListener;
import com.wefans.wefansapp.common.tool.network.model.NetImage;
import com.wefans.wefansapp.common.tool.network.model.NetJsonData;
import com.wefans.wefansapp.common.tool.network.model.NetMessage;
import com.wefans.wefansapp.common.tool.popup.DailyDialog;
import com.wefans.wefansapp.common.tool.popup.DailyDialog.OnDailyListener;
import com.wefans.wefansapp.common.tool.preference.MFSharedPreference;

/**
 * 메인화면(투표하기)
 * 
 * @author kimhyeongbae
 */
public class MainActivity extends BaseActivity implements DrawerListener, IOnNetworkListener
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // final/static property
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private final long MAGICNUM_MY_PROFILE_IMAGE_DOWNLOAD     = -1;
    private final long MAGICNUM_VOTE_LIST_LOGO_IMAGE_DOWNLOAD = -10;
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // normal property
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private DrawerLayout     m_DrawerLayout    = null;
    private FrameLayout      m_DrawerView      = null;
    private ListView         m_ListView        = null;
    
    private MFNetworkManager m_oNetworkManager = null;
    private MFDataManager    m_oDataManager    = null;
    
    private boolean          m_bFinishFlag     = false;
    private Handler          m_hdlTimer        = null;
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // life-cycle method
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        MFDebug.d(">> onCreate()");
        
        /* Back-Key 타이머를 설정하기 위한 핸들러 */
        m_hdlTimer = new Handler() {

            @Override
            public void handleMessage(Message msg)
            {
                MFDebug.d(">> handleMessage()");
                if(msg.what == 0) {
                    // 2초가 지나면 다시 Flag를 false로 바꾼다.
                    m_bFinishFlag = false;
                }
                super.handleMessage(msg);
            }
        };
        
        initialize();
        installEvent();
        showDailyDialog();
    }

    @Override
    public void finish()
    {
        MFDebug.d(">> finish()");
        
        super.finish();
    }
    
    @Override
    protected void onPause()
    {
        MFDebug.d(">> onPause()");
        
        notifyDoClaseDrawerMenu();
        
        super.onPause();
    }

    @Override
    protected void notifyDoClaseDrawerMenu()
    {
        MFDebug.d(">> notifyDoClaseDrawerMenu()");
        
        super.notifyDoClaseDrawerMenu();
        
        if( m_DrawerLayout == null ) {
            MFDebug.e(new Exception("There are NO Drawer-Layout"));
            return;
        }
        
        if( m_DrawerView == null ) {
            MFDebug.e(new Exception("There are NO Drawer-View"));
            return;
        }
        
        m_DrawerLayout.closeDrawer(m_DrawerView);
        m_sdQuickMenu.close();
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // normal method
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private void initialize()
    {
        MFDebug.d(">> initialize()");
        
        m_oNetworkManager = MFNetworkManager.getInstance(this);
        m_oDataManager    = MFDataManager.getInstance(this);
        
        //[Step 1] Contents layout adding
        FrameLayout containerContents = (FrameLayout) findViewById(R.id.FL_MAIN_CONTAINER);
        addContentsLayout(containerContents, R.layout.layout_main_contents);
        addQuickMenuLayout(containerContents);
        
        //[Step 2] Drawer menu adding
        m_DrawerView = (FrameLayout) findViewById(R.id.FL_DRAWER_LAYOUT);
        addDrawerLayout(m_DrawerView);
        
        //[Step 3] set drawer layout (root)
        m_DrawerLayout = (DrawerLayout) findViewById(R.id.DL_MAIN_NAVIGATION_LAYOUT);
        
        //[Step 4] request server data
        {
            requestGetUser();
            requestGetVote();
            requestGetAppVer();
        }
        
        m_ListView = (ListView) containerContents.findViewById(R.id.LV_MAIN_BODY_MAIN_VOTE_LIST);
        m_ListView.setAdapter(null);
    }
    
    private void installEvent()	
    {
        MFDebug.d(">> installEvent()");
        
        ((ImageButton) findViewById(R.id.IB_MAIN_HEADER_LEFT_BUTTON)).setOnClickListener(this);
        ((ImageView) findViewById(R.id.IV_MAIN_BODY_MAIN_LOGO)).setOnClickListener(this);
    }

    /**
     * 출석 확인 다이얼로그를 보여준다.
     * 
     */
    private void showDailyDialog()
    {
        MFDebug.d(">> showDailyDialog()");
        
    	final MFSharedPreference prf = new MFSharedPreference(getApplicationContext());
    	
    	if (prf.isShowDaily() && MFDataManager.getInstance(getApplicationContext()).isShowDaily()) {
    		new DailyDialog(this, new OnDailyListener() {
				
				@Override
				public void onCheckDaily(boolean bSuccess) {
					if (bSuccess) {
						prf.setShowDaily();
					}
				}
			}).show();
    		MFDataManager.getInstance(getApplicationContext()).setShowDaily(false);  		
    	}
    }

    /**
     * Drawer Menu 에 표시한 서버 데이터를 연동한다.
     * 
     */
    private void requestGetUser()
    {
        MFDebug.d(">> requestGetUser()");
        
        m_oNetworkManager.requestGetUser(this);
    }
    
    /**
     * 컨텐츠 화면에 표시할 투표 리스트를 서버 데이터로 연동한다.
     * 
     */
    private void requestGetVote()
    {
        MFDebug.d(">> requestGetVote()");
        
        m_oNetworkManager.requestGetVote(this);
    }
    
    /**
     * 앱 버전 정보를 가져온다.
     * 
     */
    private void requestGetAppVer()
    {
        MFDebug.d(">> requestGetAppVer()");
        
        m_oNetworkManager.requestGetAppVer(this);
    }
    
    /**
     * 서버로부터 받은 데이터를 기반으로 하여 드로우어 메뉴에 데이터를 채운다.
     * 
     * @param user
     */
    private void fillDrawerMenu(ResGetUser user)
    {
        MFDebug.d(">> fillDrawerMenu()");
        MFDebug.d("++ user : " + user);
        
        //[step 1] 나의 정보 채우기
        TextView tvMyNicName  = (TextView) findViewById(R.id.TV_DRAWER_MY_INFO_NICNAME);
        TextView tvMyName     = (TextView) findViewById(R.id.TV_DRAWER_MY_INFO_NAME);
        TextView tvMyStarName = (TextView) findViewById(R.id.TV_DRAWER_MY_STAR_NAME);
       
        tvMyNicName.setText(user.getNickname());
        tvMyName.setText("("+user.getName()+")");
        tvMyStarName.setText(user.getMystarname());
        
        if( user.getProfile_img() != null ) {
            m_oNetworkManager.requestImageData(MAGICNUM_MY_PROFILE_IMAGE_DOWNLOAD, user.getProfile_img(), this);
        }
        
        //[step 2] 나의 "보유별/보유 응모권/연속 출석 횟수/나의 당첨 내역" 갯수 채우기 
        TextView tvMyStars      = (TextView) findViewById(R.id.TV_DRAWER_2TH_MY_STARS);
        TextView tvMyTickets    = (TextView) findViewById(R.id.TV_DRAWER_2TH_MY_TICKETS);
        TextView tvMyAttendacne = (TextView) findViewById(R.id.TV_DRAWER_2TH_CONTINUOUS_ATTENDANCE);
        
        DecimalFormat df = new DecimalFormat("#,##0");//1000단위 콤마 찍기
        tvMyStars.setText(df.format(Double.parseDouble(user.getStarcnt())));
        tvMyTickets.setText(df.format(Double.parseDouble(user.getTicketcnt())));
        tvMyAttendacne.setText(df.format(Double.parseDouble(user.getAttendcnt())));
        
        TextView tvAppVersion   = (TextView) findViewById(R.id.TV_DRAWER_3TH_VERSION_LABEL);
        String versionText = String.format("%s (%s)", getResources().getString(R.string.drawer_menu_version_info), FEATURES.APP_VERSION);
        tvAppVersion.setText(versionText);
        
    }
    
    /**
     * 드로우어 메뉴의 진행중인 투표 갯수를 채운다.
     * 
     * @param voteCount
     */
    private void fillDrawerMenuVoteCount(int voteCount)
    {
        MFDebug.d(">> fillDrawerMenuVoteCount()");
        MFDebug.d("++ voteCount : " + voteCount);
        
        TextView tvVoteCount = (TextView) findViewById(R.id.TV_DRAWER_3TH_VOTE_NOW);
        tvVoteCount.setText(Integer.toString(voteCount));
    }
    
    /**
     * 드로우어 메뉴의 버전의 뉴배찌를 채운다.
     * 
     * @param appVersion
     */
    private void fillDrawerGetAppVer(String appVersion)
    {
        MFDebug.d(">> fillDrawerGetAppVer()");
        MFDebug.d("++ appVersion : " + appVersion);
        
        boolean bNeedUpdate = false;
        
        try {
            String[] splitLocalAppVersion  = FEATURES.APP_VERSION.split("\\.");
            String[] splitRemoteAppVersion = appVersion.split("\\.");
            
            if( Integer.parseInt(splitLocalAppVersion[0]) < Integer.parseInt(splitRemoteAppVersion[0]) ) {
                bNeedUpdate = true;
            }
            else {
                if( Integer.parseInt(splitLocalAppVersion[1]) < Integer.parseInt(splitRemoteAppVersion[1]) ) {
                    bNeedUpdate = true;
                }
            }
            
        } catch (Exception e) {
            MFDebug.e(e);
        }
        
        ((ImageView) findViewById(R.id.IV_DRAWER_3TH_VERSION_NEW_BADGE)).setVisibility((bNeedUpdate) ? View.VISIBLE : View.GONE);
    }
    
    /**
     * 서버로부터 받은 데이터를 기반으로 컨텐츠를 채운다.
     * 
     * @param vote
     */
    private void fillContents(ResGetVote vote)
    {
        MFDebug.d(">> fillContents()");
        MFDebug.d("++ vote : " + vote);
        
        //드로우어메뉴의 진행중인 투표갯수를 표시한다.
        fillDrawerMenuVoteCount(vote.getMain_data().size());
        
        List<ResGetVoteMainData> listItem = vote.getMain_data();
        CAdapter adapter = new CAdapter(this, -1, -1, listItem);
        m_ListView.setAdapter(adapter);
        
        //각 리스트의 투표 로고 이미지를 요청한다.
        for( int i=0; i<listItem.size(); i++ ) {
            ResGetVoteMainData item = listItem.get(i);
            if( item.getImg_url() != null ) {
                m_oNetworkManager.requestImageData(MAGICNUM_VOTE_LIST_LOGO_IMAGE_DOWNLOAD, item.getImg_url(), this);
            }
        }
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // network interface
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public void onNetMessage(int resultCode, NetMessage message)
    {
        MFDebug.d(">> onNetMessage()");
        MFDebug.d("++ resultCode : " + resultCode);
        MFDebug.d("++ message : " + message);
        
        try {
            //서버 여동 데이터
            if( message instanceof NetJsonData ) {
                long magicNum = ((NetJsonData) message).getMagicNum();
                String json = ((NetJsonData) message).getResponseJson();
                
                if( json == null ) {
                    throw new Exception("There are NO json data");
                }
                
                Gson gson = new Gson();
                
                /** 유저정보 가져오기 **/
                if( magicNum == MFNetworkManager.REQUEST_GET_USER ) {
                    ResGetUser user = (ResGetUser) gson.fromJson(json, ResGetUser.class);
                    if( user == null ) {
                        throw new Exception("Gson parsing error");
                    }
                    m_oDataManager.setUserInfo(user);
                    
                    fillDrawerMenu(user);
                }
                /** 투표리스트 가져오기 **/
                else if( magicNum == MFNetworkManager.REQUEST_GET_VOTE ) {
                    ResGetVote vote = (ResGetVote) gson.fromJson(json, ResGetVote.class);
                    if( vote == null ) {
                        throw new Exception("Gson parsing error");
                    }
                    
                    fillContents(vote);
                }
                /** 버전정보 가져오기 **/
                else if( magicNum == MFNetworkManager.REQUEST_GET_APP_VERSION ) {
                    ResGetAppVer appVer = (ResGetAppVer) gson.fromJson(json, ResGetAppVer.class);
                    if( appVer == null ) {
                        throw new Exception("Gson parsing error");
                    }
                    if( appVer.getApp_ver() == null ) {
                        throw new Exception("There are NO app_version");
                    }
                    
                    fillDrawerGetAppVer(appVer.getApp_ver());
                    
                    m_oDataManager.setVersionInfo(appVer);
                }
            }
            //이미지 데이터
            else if( message instanceof NetImage ) {
                String url    = ((NetImage)message).getURL();
                byte[] buffer = ((NetImage)message).getResponseBinary();
                
                if( buffer == null ) {
                    throw new Exception("There are NO image data");
                }
                
                String userImageUrl = m_oDataManager.getUserInfo().getProfile_img();
                
                //유저정보 이미지 셋팅
                if( userImageUrl.equals(url) ) {
                    Bitmap bm = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
                    ((ImageView) findViewById(R.id.IV_DRAWER_MY_PHOTO)).setImageBitmap(bm);
                }
                //리스트 데이터
                else {
                    CAdapter adapter = (CAdapter)m_ListView.getAdapter();
                    for( int i=0; i<adapter.getCount(); i++ ) {
                        ResGetVoteMainData item = adapter.getItem(i);
                        if( url.equals(item.getImg_url()) ) {
                            item.setImageBuffer(buffer);
                            adapter.notifyDataSetChanged();
                        }
                    }
                }
            }
            else {
                //ignore...
            }
        } catch(Exception e) {
            MFDebug.e(e);
        }
    }
    
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // interface method
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    @Override
    public void onClick(View v)
    {
        MFDebug.d(">> onClick()");
        
        switch( v.getId() ) {
            case R.id.IB_MAIN_HEADER_LEFT_BUTTON :
                m_DrawerLayout.openDrawer(m_DrawerView);
                break;
            case R.id.IV_MAIN_BODY_MAIN_LOGO :
                Intent i = new Intent(Intent.ACTION_VIEW);
                Uri u = Uri.parse(FEATURES.LINK_URL_MAMA_IMAGE);
                i.setData(u);
                startActivity(i);
                break;
            default :
                break;
        }
        
        super.onClick(v);
    }

    @Override
    public void onDrawerClosed(View drawerView)
    {
        MFDebug.d(">> onDrawerClosed()");
        MFDebug.d("++ drawerView : " + drawerView);
    }

    @Override
    public void onDrawerOpened(View drawerView)
    {
        MFDebug.d(">> onDrawerOpened()");
        MFDebug.d("++ drawerView : " + drawerView);
    }

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset)
    {
        MFDebug.d(">> onDrawerSlide()");
        MFDebug.d("++ drawerView : " + drawerView);
        MFDebug.d("++ slideOffset : " + slideOffset);
    }

    @Override
    public void onDrawerStateChanged(int newState)
    {
        MFDebug.d(">> onDrawerStateChanged()");
        MFDebug.d("++ newState : " + newState);
        
        String state = null;
        switch (newState) {
        case DrawerLayout.STATE_IDLE:
            state = "STATE_IDLE";
            break;
        case DrawerLayout.STATE_DRAGGING:
            state = "STATE_DRAGGING";
            break;
        case DrawerLayout.STATE_SETTLING:
            state = "STATE_SETTLING";
            break;
        default:
            state = "unknown!";
        }
        MFDebug.d("++ state : " + state);
    }
    
    /******************************************************************************************************************
     * 메인(투표하기) 리스트 어뎁터클래스
     * 
     * @author kimhyeongbae
     *
     ******************************************************************************************************************/
    class CAdapter extends ArrayAdapter<ResGetVoteMainData>
    {
        private LayoutInflater           m_oInflater           = null;
        private List<ResGetVoteMainData> m_listGetVote         = null;

        public CAdapter(Context context, int resource, int textViewResourceId, List<ResGetVoteMainData> objects)
        {
            super(context, resource, textViewResourceId, objects);
            
            m_listGetVote = objects;
            
            m_oInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            if( convertView == null ) {
                convertView = m_oInflater.inflate(R.layout.list_item_main_vote_list, null);
            }
            
            final ResGetVoteMainData item = m_listGetVote.get(position);
            
            ImageView ivLogo        = (ImageView) convertView.findViewById(R.id.IV_MAIN_BODY_LIST_ITEM_LOGO);
            TextView  tvSharedGap   = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_SHARE_GAP);
            TextView  tvRank1Title  = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_RANK1_TITLE);
            TextView  tvRank2Title  = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_RANK2_TITLE);
            TextView  tvMessage     = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_MESSAGE);
            TextView  tvRelyCount   = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_VOTE_REPLY);
            TextView  tvStarCount   = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_STAR);
            TextView  tvTicketCount = (TextView)  convertView.findViewById(R.id.TV_MAIN_BODY_LIST_ITEM_TICKET); 
            
            LinearLayout llReplyButn = (LinearLayout) convertView.findViewById(R.id.LL_MAIN_BODY_LIST_ITEM_VOTE_REPLY);
            
            if( item.getImageBuffer() != null ) {
                Bitmap bm = BitmapFactory.decodeByteArray(item.getImageBuffer(), 0, item.getImageBuffer().length);
                ivLogo.setImageBitmap(bm);
                ivLogo.setOnClickListener(new OnClickListener()
                {
                    @Override
                    public void onClick(View v)
                    {
                        Intent i = new Intent(MainActivity.this, MainDetailActivity.class);
                        i.putExtra(MainDetailActivity.INTENT_EXTRA_TAG_VOTE_IDX, item.getIdx());
                        i.putExtra(MainDetailActivity.INTENT_EXTRA_TAG_VOTE_CATEGORY_IDX, item.getCate_idx());
                        
                        startActivity(i);
                    }
                });
            }
            tvSharedGap.setText(item.getShare_gap_text());
            tvRank1Title.setText(item.getRank1_title());
            tvRank2Title.setText(item.getRank2_title());
            tvMessage.setText(item.getTitle());
            tvRelyCount.setText(item.getComment_cnt());
            tvStarCount.setText(item.getOut_num());
            tvTicketCount.setText(item.getIn_num());
            
            llReplyButn.setOnClickListener(new OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    Intent i = new Intent(MainActivity.this, ReplyActivity.class);
                    i.putExtra(ReplyActivity.INTENT_EXTRA_TAG_REPLY_IDX, item.getIdx());
                    startActivity(i);
                }
            });
            
            return convertView;
        }
    };
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        MFDebug.d(">> onKeyDown()");
        if( keyCode == KeyEvent.KEYCODE_BACK ) {
            MFDebug.d("++ KeyEvent.KEYCODE_BACK");
            MFDebug.d("++ m_bFinishFlag= " + m_bFinishFlag);
            if( !m_bFinishFlag ) {
                Toast.makeText(getApplicationContext(), "\'뒤로\' 버튼을 한 번 더 누르시면 종료합니다.", Toast.LENGTH_SHORT).show();
                m_bFinishFlag = true;
                
                m_hdlTimer.sendEmptyMessageDelayed(0, 2000);
                
                MFDebug.d("-- return (false)");
                return false;
            }
        }
        
        return super.onKeyDown(keyCode, event);
    }

}
